# model

# responsible for the setup of credentials
# therefore different information must be entered and validated
# e.g. user, regionname, key(s), aso.

from google.appengine.ext import webapp
from boto.ec2.connection import *
from boto.s3.connection import *

from Utilities import *
#from model.octopus.datastore.OctopusCloudDatabase import *
from model.octopus.datastore.OctopusCloudDatabase import OctopusCloudDatabase
from controller.BuildRegion import *

import re


class SetCredentials(webapp.RequestHandler):
    def post(self):
        utilities = Utilities()
        
        # get some basic information
        username = utilities.getUsername()
        userText = utilities.getUserText()
        url = utilities.getLogout(self)
        urlText = utilities.getUrlTextLogout()
        credentials = utilities.getCredentials(username)
         
        # get the data from the fields/url
        regionname = self.request.get('regionname')
        accessKey = self.request.get('accessKey')
        secretAccessKey = self.request.get('secretAccessKey')

        # if there is no username, then we are not logged-in so we go back to the main-page - in the else-block        
        if username:
            self.validateFormularEntries(utilities, username, userText, url, urlText, credentials, regionname, accessKey, secretAccessKey)
        else:
            self.redirect('/')
    
    # responsible for the validation of the formular entries
    def validateFormularEntries(self, utilities, username, userText, url, urlText, credentials, regionname, accessKey, secretAccessKey):
        # get the necessary region-names from the utilities-class
        amazon = utilities.getAmazonText()
        google = utilities.getGoogleText()
        openStack = utilities.getOpenStackText()
        
        # determine which region/storage-service is chosen
        if regionname == amazon or regionname == google or regionname == openStack:
            if accessKey == '' and secretAccessKey == '':
#                hintText = _('Access Key and Secret Access Key are empty - please enter your keys')
                hintText = 'Access Key and Secret Access Key are empty - please enter your keys'
                hintColor = 'red'

                self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
            elif accessKey == '':
#                hintText = _('Please enter your Access Key')
                hintText = 'Please enter your Access Key'
                hintColor = 'red'
                
                self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
            elif secretAccessKey == '':
#                hintText = _('Please enter your Secret Access Key')
                hintText = 'Please enter your Secret Access Key'
                hintColor = 'red'
                
                self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
            elif re.search(r'[^:a-zA-Z0-9]', accessKey) != None:
#                hintText = _('The given Access Key had characters that are not allowed')
                hintText = 'The given Access Key had characters that are not allowed'
                hintColor = 'red'
                
                self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
            elif re.search(r'[^\/a-zA-Z0-9+=]', secretAccessKey) != None:
#                hintText = _('The given Secret Access Key had characters that are not allowed')
                hintText = 'The given Secret Access Key had characters that are not allowed'
                hintColor = 'red'
                
                self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
            else:
                # accesKey and secretAccessKey are valid - check if credentials are correct
                try:
                    # determine the endpointURL for the selected regionname
                    endpointURL = self.getEndpointURL(utilities, regionname)
                    
                    # connect with amazon-s3-storage
                    s3Connection = utilities.getS3Connection(accessKey, secretAccessKey, endpointURL)
                    
                    # load a list of the buckets, to check if the credentials were correct
                    bucketList = s3Connection.get_all_buckets()
                except:
#                    hintText = "Octopus couldn't connect with " + regionname + " - please check your credentials."        # evtl. alternative hinweis-nachricht...
#                    hintText = _('The given credentials are wrong')
                    hintText = 'The given credentials are wrong'
                    hintColor = 'red'
                    
                    self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
                else:
                    # if the credentials were correct, then continue here
                    bucketListLength = len(bucketList)
                    
                    # determine the name of the bucket, that be used
                    currentBucketname = utilities.getBucketname(username)
                    
                    # variable responsible to remember whether a bucket already exist or not
                    bucketExisting = self.isBucketExisting(currentBucketname, bucketList, bucketListLength)
                        
                    if bucketExisting == 'false':
                        # if there is no bucket with the current username existing - create one
                        try:
                            s3Connection.create_bucket(currentBucketname)
                        except:
#                            hintText = _('The credentials are correct, but the system was not able to create the bucket')
                            hintText = 'The credentials are correct, but the system was not able to create the bucket'
                            hintColor = 'red'
                            
                            self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
                        else:
                            # check for existing buckets and then delete them
                            utilities.deleteBucketEntries(username, regionname)
                                                            
                            encryptedSecretAccessKey = utilities.doEncryption(secretAccessKey, username)
                            self.persistLoginDataIntoDatabase(utilities, regionname, accessKey, encryptedSecretAccessKey, endpointURL, username, userText, url, urlText, credentials)
                            
#                            hintText = _('The credentials are correct and the storage service is accessible')
                            hintText = 'The credentials are correct and the storage service is accessible'
                            hintColor = 'green'
                            
                            self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
                    else:
                        # if the current user has already an existing bucket
                        utilities.deleteBucketEntries(username, regionname)
                        
                        encryptedSecretAccessKey = utilities.doEncryption(secretAccessKey, username)
                        self.persistLoginDataIntoDatabase(utilities, regionname, accessKey, encryptedSecretAccessKey, endpointURL, username, userText, url, urlText, credentials)
                        
#                        hintText = _('The credentials are correct and the needed bucket already existed')
                        hintText = 'The credentials are correct and the needed bucket already existed'
                        hintColor = 'green'
                        
                        self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
        else:
#            hintText = _('Please chose a region')
            hintText = 'Please chose a region'
            hintColor = 'red'
            
            self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
    
    # compare if the currentBucket already existing in the region
    def isBucketExisting(self, currentBucketname, bucketList, bucketListLength):
        # variable responsible to remember whether a bucket already exist or not
        bucketExisting = 'false'
        
        if bucketListLength != 0:
            # iterate the bucketList to compare, if the current bucket already exist
            for i in range(bucketListLength):
                # determine the next bucketname
                bucketname = bucketList[i].name
                
                # compare the currentBucketname with the bucketname from the list
                if bucketname == currentBucketname:
                    # if the names matches, then the bucket already existing
                    bucketExisting = 'true'
        return bucketExisting
    
    # persist the login-data in to the database (OctopusCloudDatabase)
    def persistLoginDataIntoDatabase(self, utilities, regionname, accessKey, encryptedSecretAccessKey, endpointURL, username, userText, url, urlText, credentials):
        # get the endpoint-url
        endpointURL = self.getEndpointURL(utilities, regionname)
        
        if endpointURL != '':
            loginData = OctopusCloudDatabase(
                                            regionname = regionname,
                                            accessKey = accessKey,
                                            endpointURL = endpointURL,
                                            credentialType = regionname,                    # credentialType is an empty string '', instead regionname is used - maybe it's unnecessary
                                            secretAccessKey = encryptedSecretAccessKey,
                                            port = None,
                                            user = username
                                            )
        else:
#            hintText = _('An error occurred - there is no endpointURL defined for the chosen region')
            hintText = 'An error occurred - there is no endpointURL defined for the chosen region'
            hintColor = 'red'
            
            self.get(utilities, username, userText, url, urlText, hintText, hintColor, credentials)
                
        loginData.put()
        
    # depend on which regionname is chosen the endpointURL is assigned
    def getEndpointURL(self, utilities, regionname):
        # get the necessary regionnames and endpointURLs from the utilities-class
        amazon = utilities.getAmazonText()
        amazonURL = utilities.getAmazonURL()
        
        google = utilities.getGoogleText()
        googleURL = utilities.getGoogleURL()
        
        openStack = utilities.getOpenStackText()
        openStackURL = utilities.getOpenStackURL()
        
        endpointURL = ''
        if regionname == amazon:
            endpointURL = amazonURL
        elif regionname == google:
            endpointURL = googleURL
        elif regionname == openStack:
            endpointURL = openStackURL
        return endpointURL
        
    
    # responsible to put the information (hints, warnings, errors) on screen - in the '/regions'-page    
    def get(self, utilities, username, userText, url, urlText, hintText, hintColor, credentials):
        builder = BuildRegion()

        credentialsAmount = credentials.count()
        results = credentials.fetch(100)

        headline = builder.buildHeadline()
        loginTable = builder.buildLoginTable(credentialsAmount, results)
        loginForm = builder.buildLoginForm()
        content = builder.buildContent()
        
        # values for menu-placeholder
        credentialsText = utilities.getMenuTextCredentials()
        yourDataText = utilities.getMenuTextYourData()
        infoText = utilities.getMenuTextInfo()

        templateValues = {
                           'user': username,
                           'userText': userText,
                           'url': url,
                           'urlText': urlText,
                           'hintText': hintText,
                           'hintColor': hintColor,
                           'credentials': credentialsText,
                           'yourData': yourDataText,
                           'info': infoText,
                           'headline': headline,
                           'loginTable': loginTable,
                           'loginForm': loginForm,
                           'content': content
                          }

        builder.externalBuilder(self, templateValues, credentials)



        